feat(sdk): add an E2B client to the Desktop SDKs - #1784
feat(sdk): add an E2B client to the Desktop SDKs#1784devin-ai-integration[bot] wants to merge 4 commits into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
🦋 Changeset detectedLatest commit: 3d5ad37 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Package ArtifactsBuilt from e696aeb. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.46.2-devin-1787774001-desktop-e2b-client.0.tgzCLI ( npm install ./e2b-cli-2.18.1-devin-1787774001-desktop-e2b-client.0.tgzCode Interpreter JS SDK ( npm install ./e2b-code-interpreter-2.7.3-devin-1787774001-desktop-e2b-client.0.tgzDesktop JS SDK ( npm install ./e2b-desktop-2.3.4-devin-1787774001-desktop-e2b-client.0.tgzPython SDK ( pip install ./e2b-2.46.1+devin.1787774001.desktop.e2b.client-py3-none-any.whlCode Interpreter Python SDK ( pip install ./e2b_code_interpreter-2.9.2+devin.1787774001.desktop.e2b.client-py3-none-any.whlDesktop Python SDK ( pip install ./e2b_desktop-2.4.4+devin.1787774001.desktop.e2b.client-py3-none-any.whl |
There was a problem hiding this comment.
TASTE.md review
Checked the diff against the SDK design principles in TASTE.md, with emphasis on the rules this change can plausibly break: cross-language parity (T-1, T-2), option-type naming and shape (T-10, T-22, T-23), JS data-vs-class and export hygiene (T-19, T-54), config resolution (T-49, T-51), and docstrings (T-69–T-72).
Overall the desktop client is a faithful mirror of the Code Interpreter client from the base PR: options are copied rather than aliased (T-51), the whole connection surface is bound rather than a { apiKey, domain } subset (T-6), signal is deliberately excluded from the bound options (T-46), and both classes and their members carry real JSDoc/docstrings with examples (T-69, T-70).
2 violations, both inline.
Not tied to a specific changed line:
packages/desktop-python/pyproject.tomlraises the floor toe2b>=2.46.1, butClientFactory._with_params— the API this client is built on — is added by the base PR and is not in 2.46.1. The floor should be the first release that actually ships it, otherwise a user resolving to 2.46.1 gets anAttributeErroratE2B(...)construction time.packages/desktop-python/e2b_desktop/__init__.pycomputes__all__frome2b.__all__at import time. It satisfies T-54 at runtime, but the public surface is no longer greppable in the file — worth a comment pointing at the core__all__if this pattern stays.
| @@ -1,3 +1,4 @@ | |||
| export * from 'e2b' | |||
|
|
|||
| export { E2B, type E2BClientOpts } from './client' | |||
There was a problem hiding this comment.
T-54 — one flat entry point per package, and in JS "runtime values use export and type-only names use export type — never mixed". This line mixes the runtime class E2B with the type-only E2BClientOpts in a single export statement; split them so the type-only name goes through export type:
| export { E2B, type E2BClientOpts } from './client' | |
| export { E2B } from './client' | |
| export type { E2BClientOpts } from './client' |
There was a problem hiding this comment.
Done — split into export { E2B } and export type { E2BClientOpts } (1d48bf3).
| from e2b_desktop.main import Sandbox | ||
|
|
||
|
|
||
| class E2BClientParams(ApiParams, total=False): |
There was a problem hiding this comment.
T-22 / T-1 — "Option types use the Opts suffix in both languages", and the JS and Python surfaces "mirror each other 1:1 in names", differing only by language idiom (camelCase ↔ snake_case, T-1a). Opts → Params is not a language idiom, so the exported option type here should be E2BClientOpts, matching packages/desktop-js/src/client.ts:
class E2BClientOpts(ApiParams, total=False):
"""Options bound to an :class:`E2B` client, ..."""No suggestion block since the rename also touches the E2BClientParams re-export in e2b_desktop/__init__.py (and the same name is introduced for the core and Code Interpreter clients in the base PR) — worth settling in the base PR and mirroring here, so the three packages don't ship two spellings of the same type.
There was a problem hiding this comment.
Keeping E2BClientParams: it mirrors the name the released core e2b package already uses for this type, and the Opts rename would have to change the core SDK, which is out of scope here (this PR leaves packages/js-sdk/packages/python-sdk untouched). Can do the parity rename across core + both downstream packages in a follow-up. Also in 1d48bf3: the e2b>=2.46.1 floor is reverted (nothing new is needed from the core anymore) and the computed __all__ is gone, so the package's surface is plain imports again.
5632182 to
95025df
Compare
|
can you implement taste suggestions |
95025df to
1d48bf3
Compare
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
…ntouched Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Split the type-only export out of the runtime one, import ApiParams from the e2b entry point instead of its module, and drop the computed __all__. Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
The client imports E2B and ApiParams from the e2b entry point, both of which first shipped in 2.44.0. Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
1d48bf3 to
3d5ad37
Compare
Summary
Same change as #1783 (which this is stacked on), for
@e2b/desktopande2b-desktop: anE2Bclient that binds the connection configuration explicitly instead of reading it from the environment.packages/js-sdkandpackages/python-sdkare untouched — the binding is local to the package and only uses the existingClientFactoryclass state (boundOpts/_bound_api_params) the DesktopSandboxalready inherits.Python mirrors it with the local
_bind(cls, api_params)helper. Options are copied (nested header maps snapshotted,signaldropped), precedence stays per-call > client > env,undefined/Nonedoesn't clear a bound value, and clients stay isolated from each other and from the top-level exports.The new JS suite mocks the API with a local
node:httpserver, so it's excluded from the workerd leg (Node/bun/deno keep running it);desktop.startStream-style calls into envd are stubbed since only the API calls carry the bound config.Link to Devin session: https://app.devin.ai/sessions/ec1af68649fd4880a1cb27cb51d819e9
Open in Devin Desktop: https://app.devin.ai/desktop/session/ec1af68649fd4880a1cb27cb51d819e9?variant=devin
Requested by: @mishushakov